--[[
	Copyright (C) Udorn (Blackhand)
--]]

yaka = yaka or {}

local viewType = "Container"
local version = 1
if (yaka.Container and yaka.Container.version >= version) then
	return 
end

local YakaGui = LibStub("YakaGui", true)

yaka = yaka or {}
yaka.Container = {}
yaka.Container.prototype = {}
yaka.Container.metatable = {__index = yaka.Container.prototype}
setmetatable(yaka.Container.prototype, {__index = yaka.View.prototype})

yaka.Container.info = {viewType = viewType, version = version}
yaka.Container.GetViewInfo = function()
	return yaka.Container.info
end

yaka.Container.depth = 0

local log = vendor.Debug:new("Container")

local DEFAULT_LAYOUT = {layoutType = "LinearLayout"}

local function _InitFrame(self)
	frame = CreateFrame("Frame", nil, UIParent)
	frame.view = self
	frame:SetPoint("CENTER")

	self.frame = frame
end

--[[ 
	Creates a new instance.
--]]
function yaka.Container:new(cfg)
	local instance = setmetatable({}, self.metatable)
	instance:InitCfg(cfg)
	instance:InitFrame()
	return instance
end

function yaka.Container.prototype:InitCfg(cfgIn)
	yaka.View.prototype.InitCfg(self, cfgIn)
	
	local cfg = self.cfg
	cfg.backdrop = cfgIn.backdrop
    cfg.backdropColor = cfgIn.backdropColor 
    cfg.layout = cfgIn.layout or {
		layoutType = "LinearLayout",
		vertical = true
	}
	self.childsIn = cfgIn.childs
end

function yaka.Container.prototype:InitFrame()
	_InitFrame(self)
	yaka.View.prototype.InitFrame(self)
	self.childs = {}
	if (self.childsIn) then
		for k,v in pairs(self.childsIn) do
			local view = YakaGui:CreateView(v)
			self:AddChildView(view)
		end
		self.childsIn = nil
	end
	
	local cfg = self.cfg

	self.layout = YakaGui:CreateLayout(self.cfg.layout or DEFAULT_LAYOUT)
	if (cfg.backdrop) then	
		self:SetBackdrop(cfg.backdrop)
	end
	if (cfg.backdropColor) then
		self:SetBackdropColor(cfg.backdropColor)
	end
end

function yaka.Container.prototype:Layout(x, y, width, height)
	--log:Debug("Container layout x [%s] y [%s] width [%s] height [%s] type [%s]", x, y, width, height, self.cfg.viewType)
	local h = self.layout:Layout(self.childs, width, height, x, y, width, height)
	--log:Debug("got h [%s]", h)
	yaka.View.prototype.Layout(self, x, y, width, h or height)
end

function yaka.Container.prototype:SetBackdrop(backdrop)
	self.cfg.backdrop = backdrop
	self.frame:SetBackdrop(backdrop)
end

function yaka.Container.prototype:SetBackdropColor(colorArray)
	self.cfg.backdropColor = colorArray
	self.frame:SetBackdropColor(unpack(colorArray))
end	

function yaka.Container.prototype:GetMeasuredWidth()
	local w = 0
	for k,v in pairs(self.childs) do
		local mw = v:GetMeasuredWidth()
		if (mw == "fill") then
			w = "fill"
			break
		end
		local paddingLeft, paddingRight = v:GetPadding()
		if (self.cfg.layout.vertical) then
			w = math.max(w, mw + paddingLeft + paddingRight)
		else
			w = w + mw + paddingLeft + paddingRight
		end
	end
	return w
end

function yaka.Container.prototype:GetMeasuredHeight(width)
	yaka.Container.depth = yaka.Container.depth + 1
	--log:Debug("GetMeasuredHeight d[%s]", yaka.Container.depth)
	local h = 0
	for k,v in pairs(self.childs) do
		local mh = v:GetMeasuredHeight(width)
		if (mh == "fill") then
			h = "fill"
			break
		end
		local paddingLeft, paddingRight, paddingTop, paddingBottom = v:GetPadding()
		if (self.cfg.layout.vertical) then
			h = h + mh + paddingTop + paddingBottom
		else
			h = math.max(h, mh + paddingTop + paddingBottom)
		end
		--log:Debug("GetMeasuredHeight d[%s] added [%s] [%s] mh [%s] pt [%s] pb [%s]", yaka.Container.depth, v:GetViewType(), h, mh, paddingTop, paddingBottom)
	end
	--log:Debug("GetMeasuredHeight d[%s] exit [%s] vertical [%s]", yaka.Container.depth, h, self.cfg.layout.vertical)
	yaka.Container.depth = yaka.Container.depth - 1
	return h
end

function yaka.Container.prototype:AddChildView(view)
	self:SetVisibility(true) -- TODO is this really needed (caused by hide in view.initframe)
	view:SetVisibility(true)
	table.insert(self.childs, view)
	view.frame:SetParent(self.frame)
	table.sort(self.childs, function(a, b)
		return (a.cfg.order or 1000000) < (b.cfg.order or 1000000)
	end)
end

function yaka.Container.prototype:GetChildViews()
	return self.childs
end

function yaka.Container.prototype:RemoveChildViews()
	for k,v in pairs(self.childs) do
		v:SetVisibility(false)
	end
	wipe(self.childs)
end

function yaka.Container.prototype:Destroy()
	for k,v in pairs(self.childs) do
		v:Destroy()
	end
	yaka.View.prototype.Destroy(self)
end

-- register view

YakaGui:RegisterViewType(yaka.Container)